package com.lanren.common.base.impl;

import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.SystemClock;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.hjq.toast.ToastUtils;
import com.lanren.common.R;
import com.lanren.common.base.IPresenter;
import com.lanren.common.base.IView;
import com.lanren.common.interfaces.DialogClickListener;
import com.lanren.common.utils.KeyboardUtils;
import com.lanren.common.widget.status.StatusManager;
import com.lanren.common.widget.statusbar.ImmersionBar;
import com.lanren.easydialog.DialogViewHolder;
import com.lanren.easydialog.EasyDialog;
import com.lanren.easyeventbus.Event;
import com.lanren.easyeventbus.EventBusUtil;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.Random;

import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * @ClassName BaseFragment
 * @Description TODO
 * @Author chongheng.wang
 * @Date 2019/9/2 14:05
 * @Version 1.0
 */
public abstract class BaseFragment<P extends IPresenter> extends Fragment implements IView {
    private View parentView;
    protected FragmentActivity activity;
    protected P mPresenter;
    private Unbinder unbinder;
    protected ImmersionBar mImmersionBar;
    private StatusManager mStatusManager = new StatusManager();

    @LayoutRes
    public abstract int getLayoutResId();

    /**
     * fragment 创建时执行
     */
    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPresenter = createPresenter();//创建presenter
    }

    /**
     * fragment 创建后加载view
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle state) {
        parentView = inflater.inflate(getLayoutResId(), container, false);
        activity = getActivity();
        return parentView;
    }

    /**
     * fragment view创建后执行
     */
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        unbinder = ButterKnife.bind(this, view);
        if (registEventBus()) {
            EventBusUtil.register(this);
        }
        if (mPresenter != null) {
            mPresenter.attachView(this);
        }
        setStatusBar();
        doCreateView(savedInstanceState);
    }

    public View getParentView() {
        return parentView;
    }

    /**
     * 初始化views
     *
     * @param state
     */
    public abstract void doCreateView(Bundle state);

    public abstract P createPresenter();

    protected void setStatusBar() {
        mImmersionBar = ImmersionBar.with(this).init();
    }

    /**
     * 注册eventbus
     *
     * @return
     */
    protected boolean registEventBus() {
        return false;
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventBusCome(Event event) {
        if (event != null) {
            receiveEvent(event);
        }
    }


    /**
     * 接收到分发到事件,使用父类实现接口重写事件,
     * 子类根据需要去重写此父类事件,避免子类因实现接口,而强制重写接口事件导致代码过多
     *
     * @param event 事件
     */
    protected void receiveEvent(Event event) {

    }

    @Override
    public void onDestroy() {
        if (mPresenter != null) {
            mPresenter.onDestroy();//释放资源
            mPresenter = null;
        }
        if (unbinder != null) {
            unbinder.unbind();
            unbinder = null;
        }
        if (mImmersionBar != null) {
            mImmersionBar.destroy();
            mImmersionBar = null;
        }
        if (mStatusManager != null) {
            mStatusManager.removeView();
            mStatusManager = null;
        }
        if (registEventBus()) {
            EventBusUtil.unregister(this);
        }
        super.onDestroy();
    }


    @Override
    public void onDetach() {
        super.onDetach();
        this.activity = null;
    }


    @Override
    public void showLoading() {
        mStatusManager.showLoading(activity);
    }

    @Override
    public void showComplete() {
        mStatusManager.showComplete();
    }

    @Override
    public void showEmpty() {
        mStatusManager.showEmpty(getView());
    }

    @Override
    public void showNetError(View view) {
        mStatusManager.showNetError(getView());
    }

    @Override
    public void showLayout(View view, int iconId, int textId) {
        mStatusManager.showLayout(getView(), iconId, textId);
    }

    @Override
    public void showLayout(Drawable drawable, CharSequence hint) {
        mStatusManager.showLayout(getView(), drawable, hint);
    }

    @Override
    public void showMessage(String message) {
        ToastUtils.show(message);
    }

    @Override
    public void showError(int code, String msg) {

    }

    @Override
    public void showMessageDialog(final String message, final boolean isRadio, final DialogClickListener dialogClickListener) {

        new EasyDialog(activity, R.layout.dialog_message) {
            @Override
            public void onBindViewHolder(DialogViewHolder holder) {
                holder.setText(R.id.tv_dialog_message_title, "提示");
                holder.setText(R.id.tv_dialog_message_message, message);
                if (isRadio) {
                    holder.getView(R.id.tv_dialog_message_confirm).setBackgroundResource(R.drawable.dialog_message_button);
                    holder.setViewGone(R.id.tv_dialog_message_cancel);
                    holder.getView(R.id.v_dialog_message_line).setVisibility(View.GONE);
                }
                holder.setOnClick(R.id.tv_dialog_message_cancel, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dismiss();
                        dialogClickListener.onCancelClick(v);
                    }
                }).setOnClick(R.id.tv_dialog_message_confirm, new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        dismiss();
                        dialogClickListener.onConfirmClick(v);
                    }
                });
            }
        }.backgroundLight(0.2)
                .setCancelAble(false)
                .setCanceledOnTouchOutside(false)
                .showDialog(true);
    }

    @Override
    public void handleError(Exception e) {
        ToastUtils.show(e.getMessage());
    }


    /**
     * startActivity 方法优化
     */
    public void startActivity(Class<? extends Activity> cls) {
        startActivity(new Intent(activity, cls));
    }


    /**
     * startActivityForResult 方法优化
     */

    private ActivityCallback mActivityCallback;
    private int mActivityRequestCode;

    public void startActivityForResult(Class<? extends Activity> cls, ActivityCallback callback) {
        startActivityForResult(new Intent(activity, cls), null, callback);
    }

    public void startActivityForResult(Intent intent, ActivityCallback callback) {
        startActivityForResult(intent, null, callback);
    }

    public void startActivityForResult(Intent intent, @Nullable Bundle options, ActivityCallback callback) {
        if (mActivityCallback == null) {
            mActivityCallback = callback;
            // 随机生成请求码，这个请求码在 0 - 255 之间
            mActivityRequestCode = new Random().nextInt(255);
            startActivityForResult(intent, mActivityRequestCode, options);
        } else {
            // 回调还没有结束，所以不能再次调用此方法，这个方法只适合一对一回调，其他需求请使用原生的方法实现
            throw new IllegalArgumentException("Error, The callback is not over yet");
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (mActivityCallback != null && mActivityRequestCode == requestCode) {
            mActivityCallback.onActivityResult(resultCode, data);
            mActivityCallback = null;
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }


    /**
     * 处理 Activity 多重跳转：https://www.jianshu.com/p/579f1f118161
     */

    @Override
    public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
        if (selfCheckActivity(intent)) {
            hideSoftKeyboard();
            // 查看源码得知 startActivity 最终也会调用 startActivityForResult
            super.startActivityForResult(intent, requestCode, options);
        }
    }

    private String mStartActivityTag;
    private long mStartActivityTime;

    /**
     * 检查当前 Activity 是否重复跳转了，不需要检查则重写此方法并返回 true 即可
     *
     * @param intent 用于跳转的 Intent 对象
     * @return 检查通过返回true, 检查不通过返回false
     */
    protected boolean selfCheckActivity(Intent intent) {
        // 默认检查通过
        boolean result = true;
        // 标记对象
        String tag;
        if (intent.getComponent() != null) { // 显式跳转
            tag = intent.getComponent().getClassName();
        } else if (intent.getAction() != null) { // 隐式跳转
            tag = intent.getAction();
        } else { // 其他方式
            return true;
        }

        if (tag.equals(mStartActivityTag) && mStartActivityTime >= SystemClock.uptimeMillis() - 500) {
            // 检查不通过
            result = false;
        }

        mStartActivityTag = tag;
        mStartActivityTime = SystemClock.uptimeMillis();
        return result;
    }

    /**
     * 隐藏软键盘
     */
    private void hideSoftKeyboard() {
        // 隐藏软键盘，避免软键盘引发的内存泄露
        View view = activity.getCurrentFocus();
        if (view != null) {
            KeyboardUtils.hideSoftInput(activity, view);
        }
    }

    /**
     * Activity 回调接口
     */
    public interface ActivityCallback {

        /**
         * 结果回调
         *
         * @param resultCode 结果码
         * @param data       数据
         */
        void onActivityResult(int resultCode, @Nullable Intent data);
    }

}
